package org.iamd.service;

import java.io.File;
import java.util.Date;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;

import org.iamd.conf.ConfigurationFactory;
import org.iamd.conf.InitializationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * Фабрика за конфигуриране на компонента за стартиране на фонови процеси.
 * 
 * @author И. Атанасов
 */
public class ServiceConfigurationFactory implements ConfigurationFactory {

	/** Таг за клас на фонов процес. */
	private static final String CLASS_NAME = "className";

	/** Таг за период на отложено стартиране. */
	private static final String DELAY = "delay";

	/** Клас на фонов процес. */
	private static final String PATTERN = "pattern";

	/** Таг за декларация на процес. */
	private static final String SERVICE = "service";

	/** Таг за име на процес. */
	private static final String SERVICE_NAME = "serviceName";

	/** Таг за тригер. */
	private static final String TRIGGER = "trigger";

	/**
	 * @see ConfigurationFactory#initializeComponent(Map, File)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void initializeComponent(Map<String, String> params, File configFile)
			throws InitializationException {
		try {
			ServiceScheduler scheduler = ServiceScheduler.getScheduler();
			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
					.parse(configFile);
			doc.getDocumentElement().normalize();
			NodeList nList = doc.getElementsByTagName(SERVICE);
			for (int i = 0; i < nList.getLength(); i++) {
				Element eElement = (Element) nList.item(i);
				scheduler.schedule(new ServiceWrapper(getTagValue(TRIGGER, eElement), getTagValue(
						PATTERN, eElement), new Date(System.currentTimeMillis()
						+ Long.parseLong(getTagValue(DELAY, eElement))), getTagValue(SERVICE_NAME,
						eElement), (Class<? extends ABusinessService>) Class.forName(getTagValue(
						CLASS_NAME, eElement))));
			}
		} catch (Exception e) {
			throw new InitializationException(e);
		}
	}

	/**
	 * Извлича стойността на вложен таг в подадения елемент. Пример: от xml-a
	 * &#60tag&#62&#60innerTag&#62someValue&#60/innerTag&#62&#60/tag&#62 връща
	 * като резултат someValue.
	 * 
	 * @param sTag
	 *            име на вложен таг
	 * @param eElement
	 *            родителски елемент
	 * 
	 * @return извлечената стойност
	 */
	private String getTagValue(String sTag, Element eElement) {
		return eElement.getElementsByTagName(sTag).item(0).getChildNodes().item(0).getNodeValue();
	}

}